
package com.platform.api.security;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.emoji.EmojiUtil;
import com.platform.api.bzproject.model.User;
import com.platform.common.exception.PlatformBindException;
import com.platform.api.bzproject.dao.UserMapper;
import com.platform.common.util.EncryptionUtil;
import com.platform.security.dao.AppConnectMapper;
import com.platform.security.enums.App;
import com.platform.security.exception.UsernameNotFoundException;
import com.platform.security.model.AppConnect;
import com.platform.security.service.UserConnect;
import com.platform.security.service.AuthUserDetailsService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 用户详细信息
 */
@Slf4j
@Service
@AllArgsConstructor
public class AuthUserServiceImpl implements AuthUserDetailsService {

    private final UserMapper userMapper;

    private final AppConnectMapper appConnectMapper;

    private final PasswordEncoder passwordEncoder;

    @Override
    @SneakyThrows
    public UserConnect loadUserByUsername(String username) {
        if (StrUtil.isBlank(username) || !username.contains(StrUtil.COLON)) {
            throw new UsernameNotFoundException("无法获取用户信息");
        }
        String[] splitInfo = username.split(StrUtil.COLON);
        App app = App.instance(Integer.valueOf(splitInfo[0]));
        String bizUserId = splitInfo[1];
        return loadUserByAppIdAndBizUserId(app, bizUserId);
    }

    /**
     * 获取前端登陆的用户信息
     *
     * @param app
     * @param bizUserId openId
     * @return UserDetails
     * @throws UsernameNotFoundException
     */
    @Override
    public UserConnect loadUserByAppIdAndBizUserId(App app, String bizUserId) {

        User user = userMapper.getUserByBizUserId(app.value(), bizUserId);
        if (user == null) {
            throw new UsernameNotFoundException("无法获取用户信息");
        }
        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        UserConnect userConnect = new UserConnect(user.getUserId(), bizUserId, app.value(), user.getStatus() == 1);
        userConnect.setName(name);
        userConnect.setPic(user.getPic());
        return userConnect;
    }

    @Override
    public UserConnect loadUserByAppIdAndBizUserIdB(App app, String bizUserId) {

        User user = userMapper.getUserByBizUserId(app.value(), bizUserId);
        if (user == null) {
            return null;
        }
        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        UserConnect userConnect = new UserConnect(user.getUserId(), bizUserId, app.value(), user.getStatus() == 1);
        userConnect.setName(name);
        userConnect.setPic(user.getPic());

        return userConnect;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
//    @RedisLock(lockName = "insertUser", key = "#appConnect.sysAppId + ':' + #appConnect.bizUserId")
//    @Caching(evict = {
//            @CacheEvict(cacheNames = "shop_user", key = "#appConnect.sysAppId + ':' + #appConnect.bizUserId"),
//            @CacheEvict(cacheNames = "AppConnect", key = "#appConnect.sysAppId + ':' + #appConnect.bizUserId")
//    })
    public void insertUserIfNecessary(AppConnect appConnect) {
        // 进入锁后再重新判断一遍用户是否创建
        AppConnect dbAppConnect = appConnectMapper.getByBizUserId(appConnect.getBizUserId(), appConnect.getSysAppId());
        if (dbAppConnect != null) {
            return;
        }

        String userId = null;
        User user;

        if (StrUtil.isBlank(userId)) {
            userId = IdUtil.simpleUUID();
            Date now = new Date();
            user = new User();
            user.setUserId(userId);
            user.setModifyTime(now);
            user.setUserRegtime(now);
            user.setStatus(1);
            user.setNickName(EmojiUtil.toAlias(StrUtil.isBlank(appConnect.getNickName()) ? "" : appConnect.getNickName()));
            user.setPic(appConnect.getImageUrl());
            userMapper.insert(user);
        } else {
            user = userMapper.getUserByUserId(userId);
        }

        appConnect.setUserId(user.getUserId());
        appConnectMapper.insert(appConnect);
    }

    @Override
    public UserConnect loadUserByUserMail(String userMail, String loginPassword) {
        User user = userMapper.getUserByUserMail(userMail);
        if (user == null) {
            throw new PlatformBindException("用户不存在");
        }
        String paramPassword = passwordEncoder.encode(loginPassword);
        if (!passwordEncoder.matches(loginPassword, user.getLoginPassword())) {
            // 原密码不正确
            throw new PlatformBindException("密码不正确");
        }
        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        UserConnect userConnect = new UserConnect(user.getUserId(), loginPassword, user.getStatus() == 1);
        userConnect.setName(name);
        userConnect.setPic(user.getPic());
        return userConnect;
    }

    @Override
    public UserConnect loadUserByUserPhone(String mobile) {
        User user = userMapper.getUserByUserMobile(mobile);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        //手机号作为密码
        UserConnect userConnect = new UserConnect(user.getUserId(),mobile,user.getStatus() == 1);
        userConnect.setName(name);
        userConnect.setPic(user.getPic());
        return userConnect;
    }

    @Override
    public UserConnect loadUserByUserPhoneAndPassWord(String mobile,String password) {
        User user = userMapper.getUserByUserMobile(mobile);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在或密码错误");
        }

        String encryp = EncryptionUtil.combinationEncryp(password);
        if(!encryp.equals(user.getLoginPassword())){
            throw new UsernameNotFoundException("用户不存在或密码错误");
        }


        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        //手机号作为密码
        UserConnect userConnect = new UserConnect(user.getUserId(),user.getLoginPassword(),user.getStatus() == 1);
        userConnect.setName(name);
        userConnect.setPic(user.getPic());
        return userConnect;
    }

}
